package cn.jarlen.jwt.tools.crypt.device.soft;

import android.annotation.SuppressLint;

import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.X509Extension;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.bouncycastle.cert.ocsp.CertificateID;
import org.bouncycastle.cert.ocsp.OCSPException;
import org.bouncycastle.cert.ocsp.OCSPReq;
import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
import org.bouncycastle.cert.ocsp.OCSPResp;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.operator.OperatorException;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.Selector;
import org.bouncycastle.util.Store;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Vector;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;

import cn.jarlen.jwt.tools.crypt.base.StringUtils;
import cn.jarlen.jwt.tools.crypt.exception.CryptOperatorException;

public class SoftOperatorUtil {
    public static final String CERT_HEAD = "-----BEGIN CERTIFICATE-----";
    public static final String CERT_TAIL = "-----END CERTIFICATE-----";
    private static final String ALGORITHM = "SM3WithSM2";
    private static final String INIT_IV = "1234567812345678";
    private static final String PROVIDER_STR = "BC";
    private static final String SM2 = "sm2p256v1";
    public static final String ALGORITHM_SM4 = "SM4";
    public static final String ALGORITHM_NAME_CBC_PKCS7PADDING = "SM4/CBC/PKCS7Padding";
    public static final String ALGORITHM_NAME_SM2 = "SM2";

    public SoftOperatorUtil() {
    }

    public static byte[] genRandom(int len) {
        Random rd = new Random();
        byte[] arr = new byte[len];
        rd.nextBytes(arr);
        return arr;
    }

    public static byte[] sm2Encrypt(PublicKey publicKey, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance("SM2", "BC");
            cipher.init(1, publicKey);
            return cipher.doFinal(data);
        } catch (Exception var3) {
            throw new CryptOperatorException("SM2加密失败：" + var3.getMessage());
        }
    }

    public static byte[] sm2Decrypt(PrivateKey privateKey, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance("SM2", "BC");
            cipher.init(2, privateKey);
            return cipher.doFinal(data);
        } catch (Exception var3) {
            throw new CryptOperatorException("SM2解密失败：" + var3.getMessage());
        }
    }

    public static byte[] sm4Encrypt(byte[] key, byte[] data) {
        SecretKeySpec secretKey = new SecretKeySpec(key, "SM4");

        try {
            Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS7Padding", "BC");
            IvParameterSpec ivParameterSpec = new IvParameterSpec("1234567812345678".getBytes());
            cipher.init(1, secretKey, ivParameterSpec);
            return cipher.doFinal(data);
        } catch (Exception var5) {
            throw new CryptOperatorException("SM4加密失败：" + var5.getMessage());
        }
    }

    public static boolean sm4Encrypt(byte[] key, FileInputStream fileInputStream, FileOutputStream fileOutputStream) {
        SecretKeySpec secretKey = new SecretKeySpec(key, "SM4");

        try {
            Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS7Padding", "BC");
            IvParameterSpec ivParameterSpec = new IvParameterSpec("1234567812345678".getBytes());
            cipher.init(1, secretKey, ivParameterSpec);
            sm4FileExecute(cipher, fileInputStream, fileOutputStream);
            return true;
        } catch (Exception var6) {
            throw new CryptOperatorException("SM4加密失败：" + var6.getMessage());
        }
    }

    public static boolean sm4Decrypt(byte[] key, FileInputStream fileInputStream, FileOutputStream fileOutputStream) {
        SecretKeySpec secretKey = new SecretKeySpec(key, "SM4");

        try {
            Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS7Padding", "BC");
            IvParameterSpec ivParameterSpec = new IvParameterSpec("1234567812345678".getBytes());
            cipher.init(2, secretKey, ivParameterSpec);
            sm4FileExecute(cipher, fileInputStream, fileOutputStream);
            return true;
        } catch (Exception var6) {
            throw new CryptOperatorException("SM4解密失败：" + var6.getMessage());
        }
    }

    public static byte[] sm4Decrypt(byte[] key, byte[] data) {
        SecretKeySpec secretKey = new SecretKeySpec(key, "SM4");

        try {
            Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS7Padding", "BC");
            IvParameterSpec ivParameterSpec = new IvParameterSpec("1234567812345678".getBytes());
            cipher.init(2, secretKey, ivParameterSpec);
            return cipher.doFinal(data);
        } catch (Exception var5) {
            throw new CryptOperatorException("SM4解密失败：" + var5.getMessage());
        }
    }

    public static byte[] hmacWithSm3(byte[] key, byte[] data) {
        KeyParameter keyParameter = new KeyParameter(key);
        SM3Digest digest = new SM3Digest();
        HMac mac = new HMac(digest);
        mac.init(keyParameter);
        mac.update(data, 0, data.length);
        byte[] result = new byte[mac.getMacSize()];
        mac.doFinal(result, 0);
        return result;
    }

    public static byte[] hmacWithSm3(byte[] key, FileInputStream fileInputStream) {
        KeyParameter keyParameter = new KeyParameter(key);
        SM3Digest digest = new SM3Digest();
        HMac mac = new HMac(digest);
        mac.init(keyParameter);

        try {
            FileInputStream fis = fileInputStream;

            byte[] var9;
            try {
                byte[] buffer = new byte[4096];

                while (true) {
                    int bytesRead;
                    if ((bytesRead = fis.read(buffer)) == -1) {
                        byte[] hash = new byte[digest.getDigestSize()];
                        mac.doFinal(hash, 0);
                        var9 = hash;
                        break;
                    }

                    mac.update(buffer, 0, bytesRead);
                }
            } catch (Throwable var11) {
                if (fileInputStream != null) {
                    try {
                        fis.close();
                    } catch (Throwable var10) {
                        var11.addSuppressed(var10);
                    }
                }

                throw var11;
            }

            if (fis != null) {
                fis.close();
            }

            return var9;
        } catch (Exception var12) {
            throw new CryptOperatorException("HMAC-SM3文件处理失败");
        }
    }

    public static byte[] sm3(byte[] data) {
        SM3Digest digest = new SM3Digest();
        digest.update(data, 0, data.length);
        byte[] hash = new byte[digest.getDigestSize()];
        digest.doFinal(hash, 0);
        return hash;
    }

    public static byte[] sm3(FileInputStream fileInputStream) {
        SM3Digest digest = new SM3Digest();

        try {
            FileInputStream fis = fileInputStream;

            byte[] var6;
            try {
                byte[] buffer = new byte[4096];

                while (true) {
                    int bytesRead;
                    if ((bytesRead = fis.read(buffer)) == -1) {
                        byte[] hash = new byte[digest.getDigestSize()];
                        digest.doFinal(hash, 0);
                        var6 = hash;
                        break;
                    }

                    digest.update(buffer, 0, bytesRead);
                }
            } catch (Throwable var8) {
                if (fileInputStream != null) {
                    try {
                        fis.close();
                    } catch (Throwable var7) {
                        var8.addSuppressed(var7);
                    }
                }

                throw var8;
            }

            if (fis != null) {
                fis.close();
            }

            return var6;
        } catch (Exception var9) {
            throw new CryptOperatorException("SM3文件处理失败");
        }
    }

    public static boolean verifySign(PublicKey publicKey, byte[] dataBytes, byte[] sign) {
        try {
            Signature signature = Signature.getInstance("SM3WithSM2", "BC");
            signature.initVerify(publicKey);
            signature.update(dataBytes);
            return signature.verify(sign);
        } catch (Exception var4) {
            throw new CryptOperatorException(var4.getMessage());
        }
    }

    public static boolean verifySign(PublicKey publicKey, FileInputStream inputStream, byte[] sign) {
        try {
            FileInputStream fileInputStream = inputStream;

            boolean var7;
            try {
                Signature signature = Signature.getInstance("SM3WithSM2", "BC");
                signature.initVerify(publicKey);
                byte[] buffer = new byte[4096];
                while (true) {
                    int bytesRead;
                    if ((bytesRead = fileInputStream.read(buffer)) == -1) {
                        var7 = signature.verify(sign);
                        break;
                    }
                    signature.update(buffer, 0, bytesRead);
                }
            } catch (Throwable var9) {
                if (inputStream != null) {
                    try {
                        fileInputStream.close();
                    } catch (Throwable var8) {
                        var9.addSuppressed(var8);
                    }
                }
                throw var9;
            }
            if (fileInputStream != null) {
                fileInputStream.close();
            }
            return var7;
        } catch (Exception var10) {
            throw new CryptOperatorException(var10.getMessage());
        }
    }

    public static byte[] sm2Sign(PrivateKey privateKey, byte[] dataBytes) {
        try {
            Signature signature = Signature.getInstance("SM3WithSM2", "BC");
            signature.initSign(privateKey);
            signature.update(dataBytes);
            return signature.sign();
        } catch (Exception var3) {
            throw new CryptOperatorException(var3.getMessage());
        }
    }

    public static byte[] sm2Sign(PrivateKey privateKey, FileInputStream inputStream) {
        try {
            FileInputStream fileInputStream = inputStream;

            byte[] var6;
            try {
                Signature signature = Signature.getInstance("SM3WithSM2", "BC");
                signature.initSign(privateKey);
                byte[] buffer = new byte[4096];
                while (true) {
                    int bytesRead;
                    if ((bytesRead = fileInputStream.read(buffer)) == -1) {
                        var6 = signature.sign();
                        break;
                    }
                    signature.update(buffer, 0, bytesRead);
                }
            } catch (Throwable var8) {
                if (inputStream != null) {
                    try {
                        fileInputStream.close();
                    } catch (Throwable var7) {
                        var8.addSuppressed(var7);
                    }
                }
                throw var8;
            }

            if (fileInputStream != null) {
                fileInputStream.close();
            }
            return var6;
        } catch (Exception var9) {
            throw new CryptOperatorException(var9.getMessage());
        }
    }

    public static PublicKey getPublicKeyByCert(String cert) {
        try {
            X509Certificate x509Certificate = getCertFromStr(cert);
            return x509Certificate.getPublicKey();
        } catch (Exception var3) {
            throw new CryptOperatorException("从证书中获取公钥失败");
        }
    }

    @SuppressLint("NewApi")
    public static X509Certificate getX509CertificateByCert(String cert) {
        try {
            cert = cert.replace("-----BEGIN CERTIFICATE-----", "").replace("-----END CERTIFICATE-----", "");
            cert = cert.replace("\r", "").replace("\n", "");
            cert = cert.replace("\\r", "").replace("\\n", "");
            CertificateFactory certificatefactory = CertificateFactory.getInstance("X.509", "BC");
            byte[] pkByte = Base64.getDecoder().decode(cert);
            return (X509Certificate) certificatefactory.generateCertificate(new ByteArrayInputStream(pkByte));
        } catch (NoSuchProviderException | CertificateException var3) {
            throw new CryptOperatorException("解析证书失败");
        }
    }

    public static byte[] changeByteArrayLength(byte[] bb, int len) {
        if (bb.length == len) {
            return bb;
        } else {
            return bb.length < len ? fillByteArrayWithZeroInHead(bb, len) : filterByteArrayZeroInHead(bb, len);
        }
    }

    public static byte[] fillByteArrayWithZeroInHead(byte[] ss, int len) {
        if (ss.length == len) {
            return ss;
        } else {
            byte[] bs = new byte[len];
            Arrays.fill(bs, (byte) 0);
            System.arraycopy(ss, 0, bs, len - ss.length, ss.length);
            return bs;
        }
    }

    public static byte[] filterByteArrayZeroInHead(byte[] ss, int len) {
        if (ss.length < len) {
            return ss;
        } else {
            byte[] bs = new byte[len];
            System.arraycopy(ss, ss.length - len, bs, 0, len);
            return bs;
        }
    }

    public static X509Certificate readCertificateFromCer(String path) throws Exception {
        InputStream systemResourceAsStream = readInputStreamFromPath(path);
        return readCertificateFromCerInputStream(systemResourceAsStream);
    }

    public static X509Certificate readCertificateFromCerInputStream(InputStream inputStream) throws CertificateException, NoSuchProviderException {
        CertificateFactory factory = CertificateFactory.getInstance("X.509", "BC");
        return (X509Certificate) factory.generateCertificate(inputStream);
    }

    public static InputStream readInputStreamFromPath(String filename) throws FileNotFoundException {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(filename);
        if (inputStream == null) {
            inputStream = new FileInputStream(filename);
        }

        return (InputStream) inputStream;
    }

    public static byte[] lookupCrl(DirContext ctx, String crlDn, String crlAttrName) throws Exception {
        DirContext dirContext = (DirContext) ctx.lookup(crlDn);
        Attributes attributes = dirContext.getAttributes("");
        return (byte[]) attributes.get(crlAttrName).get();
    }

    public static void saveCrlFile(byte[] crlByte, String filePath) {
        try {
            FileOutputStream output = new FileOutputStream(filePath + "crl.crl");
            try {
                BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
                try {
                    bufferedOutput.write(crlByte);
                    bufferedOutput.flush();
                    output.flush();
                } catch (Throwable var8) {
                    try {
                        bufferedOutput.close();
                    } catch (Throwable var7) {
                        var8.addSuppressed(var7);
                    }
                    throw var8;
                }
                bufferedOutput.close();
            } catch (Throwable var9) {
                try {
                    output.close();
                } catch (Throwable var6) {
                    var9.addSuppressed(var6);
                }
                throw var9;
            }
            output.close();
        } catch (Exception var10) {
            throw new CryptOperatorException("crl文件写入失败");
        }
    }

    public static List<X509CRL> getCrlList(String crlFilePath) {
        try {
            List<X509CRL> list = new ArrayList();
            FileInputStream fileInputStream = new FileInputStream(crlFilePath + "crl.crl");
            CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
            X509CRL crl = (X509CRL) cf.generateCRL(fileInputStream);
            if (crl.getNextUpdate().compareTo(new Date()) > 0) {
                list.add(crl);
                return list;
            }
        } catch (Exception var5) {
        }

        return null;
    }

    public static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, OperatorException, CertificateEncodingException {
        CertificateID id = new CertificateID((new JcaDigestCalculatorProviderBuilder()).build().get(CertificateID.HASH_SHA1), new JcaX509CertificateHolder(issuerCert), serialNumber);
        OCSPReqBuilder generator = new OCSPReqBuilder();
        BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
        Vector<ASN1ObjectIdentifier> objectIdentifiers = new Vector();
        Vector<X509Extension> values = new Vector();
        objectIdentifiers.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
        values.add(new X509Extension(false, new DEROctetString(nonce.toByteArray())));
        generator.setRequestExtensions(Extensions.getInstance(new X509Extensions(objectIdentifiers, values)));
        generator.addRequest(id);
        return generator.build();
    }

    public static OCSPResp getOcspResponse(X509Certificate checkCert, X509Certificate rootCert, String url) throws GeneralSecurityException, OCSPException, IOException, OperatorException {
        if (checkCert != null && rootCert != null) {
            if (url == null) {
                return null;
            } else {
                OCSPReq request = generateOCSPRequest(rootCert, checkCert.getSerialNumber());
                byte[] array = request.getEncoded();
                URL req = new URL(url);
                HttpURLConnection con = (HttpURLConnection) req.openConnection();
                con.setRequestProperty("Content-Type", "application/ocsp-request");
                con.setRequestProperty("Accept", "application/ocsp-response");
                con.setDoOutput(true);
                con.setConnectTimeout(3000);
                con.setReadTimeout(5000);
                OutputStream out = con.getOutputStream();
                DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out));
                dataOut.write(array);
                dataOut.flush();
                dataOut.close();
                if (con.getResponseCode() != 200) {
                    throw new CryptOperatorException("ocsp响应异常,code：" + con.getResponseCode());
                } else {
                    InputStream in = (InputStream) con.getContent();
                    return new OCSPResp(in);
                }
            }
        } else {
            return null;
        }
    }

    public static BigInteger[] derSignatureDecode(byte[] encoding) throws IOException {
        ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(encoding));
        if (seq.size() != 2) {
            return null;
        } else {
            BigInteger r = ASN1Integer.getInstance(seq.getObjectAt(0)).getValue();
            BigInteger s = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();
            byte[] expectedEncoding = derSignatureEncode(r, s);
            return !org.bouncycastle.util.Arrays.constantTimeAreEqual(expectedEncoding, encoding) ? null : new BigInteger[]{r, s};
        }
    }

    public static byte[] derSignatureEncode(BigInteger r, BigInteger s) throws IOException {
        ASN1EncodableVector v = new ASN1EncodableVector();
        v.add(new ASN1Integer(r));
        v.add(new ASN1Integer(s));
        return (new DERSequence(v)).getEncoded("DER");
    }

    public static byte[][] sm2SignDerDecode(byte[] sign) throws IOException {
        return signDerDecode(sign, 32, 32);
    }

    public static byte[][] signDerDecode(byte[] sign, int rLength, int sLength) throws IOException {
        ASN1Sequence var2 = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(sign));
        if (var2.size() != 2) {
            return null;
        } else {
            BigInteger var3 = ASN1Integer.getInstance(var2.getObjectAt(0)).getValue();
            BigInteger var4 = ASN1Integer.getInstance(var2.getObjectAt(1)).getValue();
            return new byte[][]{changeByteArrayLength(BigIntegers.asUnsignedByteArray(var3), rLength), changeByteArrayLength(BigIntegers.asUnsignedByteArray(var4), rLength)};
        }
    }

    public static byte[] derSignatureEncode(byte[] r, byte[] s) throws IOException {
        return derSignatureEncode(BigIntegers.fromUnsignedByteArray(r), BigIntegers.fromUnsignedByteArray(s));
    }

    @SuppressLint("NewApi")
    private static List<X509Certificate> getCertsByCertChain(String certChainPath) {
        try {
            String content = new String(Files.readAllBytes(Paths.get(certChainPath)));
            content = content.replaceFirst("-----BEGIN PKCS7-----", "");
            content = content.replaceFirst("-----END PKCS7-----", "");
            content = content.replace("\r", "").replace("\n", "");
            content = content.replace("\\r", "").replace("\\n", "");
            ArrayList<X509Certificate> certificateList = new ArrayList();
            CMSSignedData cmsSignedData = new CMSSignedData(Base64.getDecoder().decode(content));
            Store<X509CertificateHolder> store = cmsSignedData.getCertificates();
            Collection<X509CertificateHolder> collection = store.getMatches((Selector) null);
            Iterator var6 = collection.iterator();

            while (var6.hasNext()) {
                X509CertificateHolder o = (X509CertificateHolder) var6.next();
                X509Certificate x509Certificate = (new JcaX509CertificateConverter()).setProvider("BC").getCertificate(o);
                certificateList.add(x509Certificate);
            }

            return certificateList;
        } catch (Exception var9) {
            throw new CryptOperatorException("验证证书链失败" + var9.getMessage());
        }
    }

    public static void checkCertChain(String certToBeVerify, String rootCertPath, String certChainPath) {
        X509Certificate certificateToBeVerify = getCertFromStr(certToBeVerify);

        try {
            certificateToBeVerify.checkValidity(new Date());
        } catch (Exception var17) {
            throw new CryptOperatorException("待校验证书已过期");
        }

        if (!StringUtils.isBlank(rootCertPath) && !StringUtils.isBlank(certChainPath)) {
            Principal issuerDNOfTBV = certificateToBeVerify.getIssuerDN();
            boolean isInCertChain = false;

            try {
                List certList = getCertsByCertChain(certChainPath);

                try {
                    X509Certificate rootCert = readCertificateFromCer(rootCertPath);
                    PublicKey rootPubKey = rootCert.getPublicKey();
                    ((X509Certificate) certList.get(0)).verify(rootPubKey);
                } catch (Exception var16) {
                    throw new CryptOperatorException("当前证书不是由根证书签发");
                }

                Principal prevSubjectDN = null;
                Date date = new Date();

                for (int i = 0; i < certList.size(); ++i) {
                    X509Certificate cert = (X509Certificate) certList.get(i);
                    Principal issuerDN = cert.getIssuerDN();
                    Principal subjectDN = cert.getSubjectDN();
                    if (prevSubjectDN != null) {
                        if (!issuerDN.equals(prevSubjectDN)) {
                            throw new CryptOperatorException("证书链验证失败，存在非法的证书");
                        }

                        try {
                            PublicKey publickey = ((X509Certificate) certList.get(i - 1)).getPublicKey();
                            ((X509Certificate) certList.get(i)).verify(publickey);
                            ((X509Certificate) certList.get(i)).checkValidity(date);
                        } catch (Exception var15) {
                            throw new CryptOperatorException("证书链验证失败，存在非法的证书");
                        }
                    }

                    prevSubjectDN = subjectDN;
                    if (issuerDNOfTBV.equals(subjectDN)) {
                        try {
                            certificateToBeVerify.verify(cert.getPublicKey());
                        } catch (Exception var14) {
                            throw new CryptOperatorException("证书链校验失败");
                        }

                        isInCertChain = true;
                        break;
                    }
                }

                if (!isInCertChain) {
                    throw new CryptOperatorException("证书链不包含被校验证书的颁发者");
                }
            } catch (Exception var18) {
                throw new CryptOperatorException(var18.getMessage());
            }
        }
    }

    public static X509Certificate getCertFromStr(String str) {
        str = str.replace("-----BEGIN CERTIFICATE-----", "").replace("-----END CERTIFICATE-----", "");
        str = str.replace("\r", "").replace("\n", "");
        str = str.replace("\\r", "").replace("\\n", "");
        X509Certificate x509Cert = getCertFromB64(str);
        if (x509Cert == null) {
            x509Cert = getCertFromFullStr(str);
        }

        if (x509Cert == null) {
            x509Cert = getCertFromStr16(str);
        }

        if (null == x509Cert) {
            throw new CryptOperatorException("证书解析失败");
        } else {
            return x509Cert;
        }
    }

    public static X509Certificate getCertFromFullStr(String str) {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
            InputStream inStream = new ByteArrayInputStream(str.getBytes());
            X509Certificate x509Cert = (X509Certificate) cf.generateCertificate(inStream);
            return x509Cert;
        } catch (Exception var4) {
            return null;
        }
    }

    @SuppressLint("NewApi")
    public static synchronized X509Certificate getCertFromB64(String b64) {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
            byte[] bsCert = Base64.getDecoder().decode(b64);
            InputStream inStream = new ByteArrayInputStream(bsCert);
            X509Certificate x509Cert = (X509Certificate) cf.generateCertificate(inStream);
            return x509Cert;
        } catch (Exception var5) {
            return null;
        }
    }

    public static X509Certificate getCertFromStr16(String str) {
        byte[] bs = hex2byte(str);

        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
            InputStream inStream = new ByteArrayInputStream(bs);
            X509Certificate x509Cert = (X509Certificate) cf.generateCertificate(inStream);
            return x509Cert;
        } catch (Exception var5) {
            return null;
        }
    }

    @SuppressLint("NewApi")
    public static byte[] hex2byte(String str) {
        if (null != str && !"".equals(str)) {
            str = str.trim();
            StringBuilder sb = new StringBuilder(str);
            int len = sb.length();
            int binarySize = 2;
            if (len != 0 && len % binarySize != 1) {
                byte[] b = new byte[len / 2];

                try {
                    for (int i = 0; i < len; i += binarySize) {
                        Integer value = Integer.decode("0x" + sb.substring(i, i + 2));
                        b[i / 2] = value.byteValue();
                    }

                    return b;
                } catch (Exception var6) {
                    return new byte[0];
                }
            } else {
                return new byte[0];
            }
        } else {
            return new byte[0];
        }
    }

    public static byte[] preSm3(PublicKey publicKey, byte[] userID) {
        SM3Digest digest = new SM3Digest();
        digest.reset();
        int len = userID.length * 8;
        digest.update((byte) (len >> 8 & 255));
        digest.update((byte) (len & 255));
        digest.update(userID, 0, userID.length);
        ECPublicKey ecPublicKey = (ECPublicKey) publicKey;
        ECPoint ecPoint = ecPublicKey.getQ();
        ECParameterSpec ecParams = ecPublicKey.getParameters();
        addFieldElement(digest, ecParams.getCurve().getA());
        addFieldElement(digest, ecParams.getCurve().getB());
        addFieldElement(digest, ecParams.getG().getAffineXCoord());
        addFieldElement(digest, ecParams.getG().getAffineYCoord());
        addFieldElement(digest, ecPoint.getAffineXCoord());
        addFieldElement(digest, ecPoint.getAffineYCoord());
        byte[] result = new byte[digest.getDigestSize()];
        digest.doFinal(result, 0);
        return result;
    }

    private static void addFieldElement(Digest digest, ECFieldElement v) {
        byte[] p = v.getEncoded();
        digest.update(p, 0, p.length);
    }

    public static ECPublicKey createECPublicKey(byte[] xBytes, byte[] yBytes) {
        try {
            X9ECParameters sm2Parameters = CustomNamedCurves.getByName("sm2p256v1");
            ECParameterSpec parameterSpec = new ECParameterSpec(sm2Parameters.getCurve(), sm2Parameters.getG(), sm2Parameters.getN(), sm2Parameters.getH());
            ECPoint ecPoint = sm2Parameters.getCurve().createPoint(new BigInteger(1, xBytes), new BigInteger(1, yBytes));
            ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(ecPoint, parameterSpec);
            KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
            return (ECPublicKey) keyFactory.generatePublic(publicKeySpec);
        } catch (Exception var7) {
            throw new CryptOperatorException("公钥x,y转公钥对象失败");
        }
    }

    private static void sm4FileExecute(Cipher cipher, FileInputStream fileInputStream, FileOutputStream fileOutputStream) {
        try {
            FileInputStream inputFileStream = fileInputStream;

            try {
                FileOutputStream outputFileStream = fileOutputStream;

                try {
                    byte[] inputBuffer = new byte[cipher.getBlockSize()];
                    byte[] outputBuffer = new byte[cipher.getOutputSize(inputBuffer.length)];

                    int bytesRead;
                    int finalOutputLength;
                    while ((bytesRead = inputFileStream.read(inputBuffer)) != -1) {
                        finalOutputLength = cipher.update(inputBuffer, 0, bytesRead, outputBuffer, 0);
                        if (finalOutputLength > 0) {
                            outputFileStream.write(outputBuffer, 0, finalOutputLength);
                        }
                    }

                    finalOutputLength = cipher.doFinal(outputBuffer, 0);
                    if (finalOutputLength > 0) {
                        outputFileStream.write(outputBuffer, 0, finalOutputLength);
                    }
                } catch (Throwable var11) {
                    if (fileOutputStream != null) {
                        try {
                            outputFileStream.close();
                        } catch (Throwable var10) {
                            var11.addSuppressed(var10);
                        }
                    }

                    throw var11;
                }

                if (outputFileStream != null) {
                    outputFileStream.close();
                }
            } catch (Throwable var12) {
                if (fileInputStream != null) {
                    try {
                        inputFileStream.close();
                    } catch (Throwable var9) {
                        var12.addSuppressed(var9);
                    }
                }

                throw var12;
            }

            if (inputFileStream != null) {
                inputFileStream.close();
            }

        } catch (Exception var13) {
            throw new CryptOperatorException(var13.getMessage());
        }
    }

    static {
        if (Security.getProvider("BC") == null) {
            Security.addProvider(new BouncyCastleProvider());
        }

    }
}
